﻿
using RedisHelper.Config;
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RedisHelper.Proxy
{
    /// <summary>
    /// Redis缓存管理器。
    /// </summary>
    public class RedisManager
    {

        static PooledRedisClientManager pooledRedis;
        public static Config.RedisConfig redisConfig;
        static RedisManager()
        {
            redisConfig = RedisConfigPool.GetRedisConfig();
            List<string> readWriteHosts = new List<string>();
            var readOnlyHosts = new List<string>();
            redisConfig.ReadWriteHosts.ForEach(p =>
            {
                readWriteHosts.Add(p.Host);
            });
            redisConfig.ReadOnlyHosts.ForEach(p =>
            {
                readOnlyHosts.Add(p.Host);
            });
            pooledRedis = new PooledRedisClientManager(readWriteHosts.ToList(), readOnlyHosts.ToArray(), redisConfig.RedisClientManagerConfig);
        }

        /// <summary>
        /// 获取Redis客户端实例
        /// </summary>
        /// <returns>返回客户端实例</returns>
        public static IRedisClient GetClient()
        {
            IRedisClient redis = pooledRedis.GetClient();
            if (redisConfig.ConnectTimeout > 0)
            {
                redis.ConnectTimeout = redisConfig.ConnectTimeout;
            }
            if (redisConfig.RetryCount > 0)
            {
                redis.RetryCount = redisConfig.RetryCount;
            }
            if (redisConfig.RetryTimeout > 0)
            {
                redis.RetryTimeout = redisConfig.RetryTimeout;
            }
            if (redisConfig.SendTimeout > 0)
            {
                redis.SendTimeout = redisConfig.SendTimeout;
            }
            redis.Password = redisConfig.Password;
            return redis;
        }

        /// <summary>
        /// 添加实体集合到缓存中
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="entities">实体集合</param>
        /// <returns>成功返回True，失败返回False</returns>
        public static bool SetListEntity<T>(string key, List<T> entities)
        {
            using (IRedisClient redis = GetClient())
            {
                return redis.Set(key, entities);
            }
        }

        /// <summary>
        /// 添加指定类型的对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">键名</param>
        /// <param name="entity">添加的对象</param>
        /// <returns>成功返回True，失败返回False</returns>
        public static bool SetEntity<T>(string key, T entity)
        {
            using (IRedisClient redis = GetClient())
            {
                return redis.Set<T>(key, entity);
            }
        }

        /// <summary>
        /// 添加字符文本
        /// </summary>
        /// <param name="key">缓存键名</param>
        /// <param name="text">文本</param>
        /// <returns>返回True或者False</returns>
        public static bool SetText(string key, string text)
        {
            using (IRedisClient redis = GetClient())
            {
                return redis.Set<string>(key, text);
            }
        }

        /// <summary>
        /// 根据键名获取集合列表
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="key">键名</param>
        /// <returns>返回key对应的集合列表，否则返回null</returns>
        public static List<T> GetListEntities<T>(string key)
        {
            using (IRedisClient redis = GetClient())
            {
                return redis.Get<List<T>>(key);
            }
        }

        /// <summary>
        /// 获取文本
        /// </summary>
        /// <param name="key">缓存键名</param>
        /// <returns>返回对应的键值或者string.Empty</returns>
        public static string GetText(string key)
        {
            using (IRedisClient redis = GetClient())
            {
                return redis.Get<string>(key) ?? string.Empty;
            }
        }

        /// <summary>
        /// 获取所有键
        /// </summary>
        /// <returns>返回所有缓存键</returns>
        public static List<string> GetAllKeys()
        {
            using (IRedisClient redis = GetClient())
            {
                return redis.GetAllKeys();
            }
        }

        /// <summary>
        /// 获取指定类型列表
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="keys">键集合</param>
        /// <returns>返回集合列表</returns>
        public static Dictionary<string, T> GetItems<T>(List<string> keys)
        {
            if (keys != null && keys.Count > 0)
            {
                using (IRedisClient redis = GetClient())
                {
                    return (Dictionary<string, T>)redis.GetAll<T>(keys);
                }
            }
            return new Dictionary<string, T>();
        }

        /// <summary>
        /// 删除指定键缓存
        /// </summary>
        /// <param name="key">键名</param>
        /// <returns>成功返回True，失败返回False</returns>
        public static bool Remove(string key)
        {
            using (IRedisClient redis = GetClient())
            {
                return redis.Remove(key);
            }
        }

        /// <summary>
        /// 删除指定键缓存
        /// </summary>
        /// <param name="keys">键名</param>
        public static void RemoveAll(List<string> keys)
        {
            if (keys != null && keys.Count > 0)
            {
                using (IRedisClient redis = GetClient())
                {
                    redis.RemoveAll(keys);
                }
            }
        }

        /// <summary>
        /// 清空缓存
        /// </summary>
        public static void Clear()
        {
            using (IRedisClient redis = GetClient())
            {
                List<string> keys = GetAllKeys();
                RemoveAll(keys);
            }
        }

        /// <summary>
        /// 清空数据库
        /// </summary>
        public static void FlushAll()
        {
            using (IRedisClient redis = GetClient())
            {
                redis.FlushAll();
            }
        }
    }
}
